﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.Windows.Navigation;
using GisSharpBlog.NetTopologySuite.IO;
using GeoAPI.Geometries;
using GisSharpBlog.NetTopologySuite.Geometries;
using System.Collections.ObjectModel;
using DeepEarth.Core;
using de = DeepEarth.Toolkit.Geometry.Data;
using DeepEarth.Toolkit.Controls;
using DeepEarth.Toolkit.Geometry.Data;

namespace ExampleApplication.Examples
{
    public partial class EditExistingShapes : Page
    {
        public EditExistingShapes()
        {
            InitializeComponent();

            this.LayoutUpdated += EditExistingShapes_LayoutUpdated;            
        }

        Digitizer digitizer;
        void EditExistingShapes_LayoutUpdated(object sender, EventArgs e)
        {
            if (this.navigationPanel.VerticalPanel != null)
            {
                this.LayoutUpdated -= EditExistingShapes_LayoutUpdated;
                StackPanel vertical = this.navigationPanel.VerticalPanel as StackPanel;
                digitizer = vertical.Children[1] as Digitizer;
                LoadGeometries();
            }
        }


        // Executes when the user navigates to this page.
        protected override void OnNavigatedTo(NavigationEventArgs e)
        {
        }

        // Note the two way binding of the Position property in the map template selector
        void LoadGeometries()
        {
            var wktReader = new WKTReader(new GeometryFactory(new PrecisionModel(), 4326));
            IGeometry geometry = wktReader.Read("GEOMETRYCOLLECTION( POLYGON((0 0, 3 0, 0 3, 0 0)), POINT(5 5) )");

            de.Geometry deGeo = CreateGeometry(geometry);

            var primitives = Flatten(deGeo);

            foreach (var polygon in primitives.OfType<PolygonGeometry>())
            {
                polygon.StrokeThickness = 2;
                polygon.Stroke = new SolidColorBrush(ColorFromString("#FF1B0AA5"));
                polygon.Fill = new SolidColorBrush(ColorFromString("#88677E1E"));
            }

            // digitizer doesn't handle multigeometries
            foreach (var primitive in primitives)
            {
                digitizer.AddDrawnObject(primitive);
            }            
        }

        de.Geometry CreateGeometry(IGeometry geo)
        {
            var locations = new ObservableCollection<DeepEarth.Core.Location>();
            if (geo != null)
            {
                foreach (ICoordinate coordinate in geo.Coordinates)
                {
                    var location = new DeepEarth.Core.Location { Latitude = coordinate.Y, Longitude = coordinate.X };
                    locations.Add(location);
                }

                switch (geo.GeometryType)
                {
                    case "Polygon":
                        return new de.PolygonGeometry { Locations = locations };

                    case "LineString":
                        return new de.LineStringGeometry { Locations = locations };

                    case "Point":
                        var point = new de.PushpinGeometry();                        

                        if (locations.Count > 0)
                        {
                            point.Position = locations[0];
                        }

                        return point;

                    case "MultiLineString":
                    case "MultiPolygon":
                    case "GeometryCollection":
                        var geometryCollection = new de.GeometryCollection();

                        var igc = geo as IGeometryCollection;
                        foreach (IGeometry geometry in igc.Geometries)
                        {
                            geometryCollection.Geometries.Add(CreateGeometry(geometry));
                        }
                        return geometryCollection;

                }
            }
            return null;
        }

        List<de.Geometry> Flatten (de.Geometry geometry)
        {
            de.GeometryCollection gec = geometry as de.GeometryCollection;

            if (gec != null)
            {
                return gec.Geometries.SelectMany(c => Flatten(c)).ToList();
            }
            else
            {
                return new List<de.Geometry> { geometry };
            }
        }

        Color ColorFromString(string color)
        {
            if (color.Length < 9)
                throw new ArgumentException("Invalid color string");
           
            string actual = color.StartsWith("#") ? color.Substring(1) : color;

            if (actual.Length != 8)
                throw new ArgumentException("Invalid color string");

            int a = int.Parse(actual.Substring(0, 2), System.Globalization.NumberStyles.HexNumber);
            int r = int.Parse(actual.Substring(2, 2), System.Globalization.NumberStyles.HexNumber);
            int g = int.Parse(actual.Substring(4, 2), System.Globalization.NumberStyles.HexNumber);
            int b = int.Parse(actual.Substring(6, 2), System.Globalization.NumberStyles.HexNumber);

            return Color.FromArgb((byte)a, (byte)r, (byte)g, (byte)b);
        }
       
    }
}
